#ifndef _COMM_HPP_
#define _COMM_HPP_

#include<iostream>
#include<cerrno>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/shm.h>


#define PATHNAME "."
#define PROJ_ID 0x66
#define MAX_SIZE 4096//单位是字节 建议是4KB的整数倍 系统分配共享内存是以4KB为单位的--内存划分内存块的基本单位page

key_t getkey()
{
    key_t k=ftok(PATHNAME,PROJ_ID);
    if(k<0)
    {
        std::cerr<<errno<<": "<<strerror(errno)<<std::endl;
        exit(1);
    }
    return k;
}

int getShmHelper(key_t k,int flags)
{
    //k是要shmget设置进入共享内存属性中的，用来标识该共享内存在内核中的唯一性
    //shmid vs k
    //fd    vs inode
    int shmid=shmget(k,MAX_SIZE,flags);
    if(shmid<0)
    {
        std::cerr<<errno<<": "<<strerror(errno)<<std::endl;
        exit(2);
    }
    return shmid;
}

int getShm(key_t k)
{
    return getShmHelper(k,IPC_CREAT);//不存在就创建，存在就获取返回
}

int createShm(key_t k)
{
    return getShmHelper(k,IPC_CREAT | IPC_EXCL | 0600);//0600表示传入的权限选项 
}

void* attachShm(int shmid)
{
    void* mem=shmat(shmid,nullptr,0);
    if((long long)mem==-1L)
    {
        std::cerr<<"shmat:"<<errno<<": "<<strerror(errno)<<std::endl;
        exit(3);
    }
    return mem;
}

void detachShm(void* start)
{
    if(shmdt(start)==-1)
    {
        std::cerr<<"shmdt:"<<errno<<": "<<strerror(errno)<<std::endl;

    }
}

void delShm(int shmid)
{
    if(shmctl(shmid,IPC_RMID,nullptr)==-1)
    {
        std::cerr<<errno<<": "<<strerror(errno)<<std::endl;
    }
}

#endif